Linux 脏管道漏洞允许具有根权限的写访问
点击上方蓝字“Ots安全”一起玩耍
Linux内核漏洞允许以root权限进行写访问
另一个严重的内核错误“ Dirty Pipe ”已被发现,它影响自 5.8 以来运行内核版本的所有 Linux 机器。此漏洞允许覆盖任意只读文件中的数据,这会导致权限提升,因为非特权进程可以将代码注入根进程。
被追踪为 CVE-2022-0847的 Dirty Pipe 漏洞在某种程度上类似于 Linux 中名为“ Dirty Cow ”的流行讨厌的错误,但更容易被利用。该漏洞是由CM4all 托管 的安全研究员 Max Kellermann发现的。
当 Kellermann 从其托管客户之一获得有关损坏文件的支持票时,他开始修复该问题。在查看问题时,他发现其中一台日志服务器上有损坏的日志文件,可以对其进行解压缩,但 gzip 报告了 CRC 错误。“我无法解释为什么它会损坏,但我认为夜间拆分过程已经崩溃并留下了一个损坏的文件。我手动修复了文件的 CRC,关闭了票证,很快就忘记了这个问题。” 凯勒曼在博文上写道。
后来,他在他们的服务器上发现了多个类似的问题。每次,文件的内容看起来都是正确的,只有文件末尾的 CRC 是错误的。在深入研究了这个问题后,他得出了一个结论:这一定是一个内核错误。
通过查看内核代码和一些快速检查,他确认该错误存在于影响 Linux 5.10 (Debian Bullseye) 但不影响 Linux 4.19 (Debian Buster) 的内核管道中。
管道是一种用于单向进程间通信的工具。一端用于将数据推送到其中,另一端可以提取该数据。Linux 内核通过一个 struct pipe_buffer 环来实现这一点,每个 struct pipe_buffer 都指向一个页面。第一次写入管道会分配一个页面(用于 4 kB 数据的空间)。如果最近的写入没有完全填满页面,则以下写入可能会附加到该现有页面而不是分配新页面。这就是“匿名”管道缓冲区的工作方式(anon_pipe_buf_ops)。
利用 脏管道漏洞 ( CVE-2022-0847)
在他的研究中,Kellermann 了解到,即使在没有写入器(用于二等分的写入器)的情况下,也可以在(几乎)任意位置使用任意数据覆盖页面缓存,并且没有时间限制。但是有一些限制是:
攻击者必须具有读取权限(因为它需要将页面拼接()到管道中)
偏移量不能在页面边界上(因为该页面的至少一个字节必须已拼接到管道中)
写入不能跨越页面边界(因为将为其余部分创建一个新的匿名缓冲区)
文件无法调整大小(因为管道有自己的页面填充管理,并且不会告诉页面缓存附加了多少数据)
要利用此漏洞,您需要:
创建管道。
用任意数据填充管道(在所有环条目中设置 PIPE_BUF_FLAG_CAN_MERGE 标志)。
排空管道(保留在 struct pipe_inode_info 环上的所有 struct pipe_buffer 实例中设置的标志)。
将目标文件(使用 O_RDONLY 打开)中的数据从目标偏移之前的位置拼接到管道中。
将任意数据写入管道;由于设置了 PIPE_BUF_FLAG_CAN_MERGE,此数据将覆盖缓存的文件页面,而不是创建新的匿名结构 pipe_buffer。
为了让这个漏洞更有趣,它不仅可以在没有写入权限的情况下工作,它还可以用于不可变文件、只读 btrfs 快照和只读挂载(包括 CD-ROM 挂载)。这是因为页面缓存始终是可写的(由内核),并且写入管道从不检查任何权限。
由未初始化的“pipe_buffer.flags”变量引起的 Dirty Pipe 漏洞 (CVE-2022-0847)的概念验证利用也已发布。它演示了如何覆盖页面缓存中的任何文件内容,即使该文件不允许被写入、不可变或处于只读挂载状态。
该漏洞已在 Linux 5.16.11、5.15.25 和 5.10.102 中修复。由于该漏洞易于利用且 PoC 已经发布,我们强烈建议大家(特别是所有 Linux Web 服务器管理员)更新 Linux 服务器。